<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>FabGL: VGA/Songs/Songs.ino</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(initResizable);
/* @license-end */</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="doxygen-awesome.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">FabGL
   </div>
   <div id="projectbrief">ESP32 Display Controller and Graphics Library</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('_v_g_a_2_songs_2_songs_8ino-example.html','');});
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
  <div class="headertitle">
<div class="title">VGA/Songs/Songs.ino</div>  </div>
</div><!--header-->
<div class="contents">
<p>Music and sound demo, from Carles Oriol</p>
<div class="fragment"><div class="line"><span class="preprocessor">#if CONFIG_FREERTOS_UNICORE</span></div><div class="line"><span class="preprocessor">#define ARDUINO_RUNNING_CORE 0</span></div><div class="line"><span class="preprocessor">#else</span></div><div class="line"><span class="preprocessor">#define ARDUINO_RUNNING_CORE 1</span></div><div class="line"><span class="preprocessor">#endif</span></div><div class="line"></div><div class="line"><span class="preprocessor">#define PLAY_SOUND_PRIORITY (configMAX_PRIORITIES - 1)</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="fabgl_8h.html">fabgl.h</a>&quot;</span></div><div class="line"></div><div class="line"><a name="_a0"></a><a class="code" href="classfabgl_1_1_v_g_a16_controller.html">fabgl::VGA16Controller</a> VGAController;</div><div class="line"><a name="_a1"></a><a class="code" href="classfabgl_1_1_canvas.html">fabgl::Canvas</a>        canvas(&amp;VGAController);</div><div class="line"><a name="_a2"></a><a class="code" href="classfabgl_1_1_p_s2_controller.html">fabgl::PS2Controller</a> PS2Controller;</div><div class="line">SoundGenerator       soundGenerator;</div><div class="line"><a name="_a3"></a><a class="code" href="classfabgl_1_1_terminal.html">fabgl::Terminal</a>      Terminal;</div><div class="line"></div><div class="line"><span class="keyword">enum</span> wavetype { WAVE_SQUARE, WAVE_SINE, WAVE_TRIANGLE, WAVE_SAW, WAVE_NOISE };</div><div class="line"><span class="keyword">enum</span> modfreqmode { MODFREQ_NONE, MODFREQ_TO_END, MODFREQ_TO_RELEASE, MODFREQ_TO_SUSTAIN  };</div><div class="line"></div><div class="line"><span class="keyword">struct </span>playsounddata</div><div class="line">{</div><div class="line">  <span class="keywordtype">long</span> attack; <span class="comment">// time in millis (for now)</span></div><div class="line">  <span class="keywordtype">long</span> decay; <span class="comment">// time in millis (for now)</span></div><div class="line">  <span class="keywordtype">int</span> sustain; <span class="comment">// 0-127 range (over volume)</span></div><div class="line">  <span class="keywordtype">long</span> release; <span class="comment">// time in millis (for now)</span></div><div class="line"></div><div class="line">  wavetype wave; <span class="comment">// square, sine, triangle, saw, noise</span></div><div class="line">  <span class="keywordtype">int</span> volume;</div><div class="line">  <span class="keywordtype">int</span> durationms;</div><div class="line">  <span class="keywordtype">int</span> freq_start;</div><div class="line">  <span class="keywordtype">int</span> freq_end;</div><div class="line">  modfreqmode modfreq;</div><div class="line"></div><div class="line">};</div><div class="line"></div><div class="line"><span class="preprocessor">#define NOTESTEP 1.0594630943593</span></div><div class="line"></div><div class="line">SquareWaveformGenerator swg;</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> setup() {</div><div class="line"></div><div class="line">  Serial.<a name="a4"></a><a class="code" href="classfabgl_1_1_terminal_aebaecc1fa474fddc48dd5778024b19a5.html#aebaecc1fa474fddc48dd5778024b19a5">begin</a>(115200);</div><div class="line">  <span class="comment">//PS2Controller.begin(PS2Preset::KeyboardPort0); //, KbdMode::GenerateVirtualKeys)</span></div><div class="line"></div><div class="line">  VGAController.begin();</div><div class="line">  VGAController.<a name="a5"></a>setResolution(<a name="a6"></a><a class="code" href="fabglconf_8h_a86b59f35df218823a6165d836cfc22c0.html#a86b59f35df218823a6165d836cfc22c0">VGA_640x400_70Hz</a>);</div><div class="line">  VGAController.moveScreen(5, 0);</div><div class="line"></div><div class="line">  soundGenerator.setVolume(126);</div><div class="line">  soundGenerator.play(<span class="keyword">true</span>);</div><div class="line">  soundGenerator.attach( &amp;swg);</div><div class="line"></div><div class="line">  Terminal.<a class="code" href="classfabgl_1_1_terminal_aebaecc1fa474fddc48dd5778024b19a5.html#aebaecc1fa474fddc48dd5778024b19a5">begin</a>(&amp;VGAController);</div><div class="line">  <span class="comment">//Terminal.connectLocally();</span></div><div class="line">  Terminal.<a name="a7"></a><a class="code" href="classfabgl_1_1_terminal_a2da678d7453efcfed190b99ac93a53d0.html#a2da678d7453efcfed190b99ac93a53d0">clear</a>();</div><div class="line">  Terminal.<a name="a8"></a><a class="code" href="classfabgl_1_1_terminal_aace245bfe6cab7b4339bd691077e1c23.html#aace245bfe6cab7b4339bd691077e1c23">enableCursor</a>(<span class="keyword">true</span>);</div><div class="line"></div><div class="line">  Terminal.<a name="a9"></a><a class="code" href="classfabgl_1_1_terminal_a7c66fc8d559f4956d4ccea196299bca7.html#a7c66fc8d559f4956d4ccea196299bca7">write</a>( <span class="stringliteral">&quot;SoundChip simulator by Carles Oriol 2020\r\n\r\n&quot;</span>);</div><div class="line"></div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> iPlaySound( <span class="keywordtype">void</span> *pvParameters )</div><div class="line">{</div><div class="line">  playsounddata psd = *(playsounddata *)pvParameters;</div><div class="line"></div><div class="line">  WaveformGenerator *pwave = <span class="keyword">nullptr</span>;</div><div class="line">  <span class="keywordflow">if</span> ( psd.wave == WAVE_SQUARE)   pwave = <span class="keyword">new</span> SquareWaveformGenerator();</div><div class="line">  <span class="keywordflow">if</span> ( psd.wave == WAVE_SINE)     pwave = <span class="keyword">new</span> SineWaveformGenerator();</div><div class="line">  <span class="keywordflow">if</span> ( psd.wave == WAVE_TRIANGLE) pwave = <span class="keyword">new</span> TriangleWaveformGenerator();</div><div class="line">  <span class="keywordflow">if</span> ( psd.wave == WAVE_SAW)      pwave = <span class="keyword">new</span> SawtoothWaveformGenerator();</div><div class="line">  <span class="keywordflow">if</span> ( psd.wave == WAVE_NOISE)    pwave = <span class="keyword">new</span> NoiseWaveformGenerator();</div><div class="line"></div><div class="line">  <span class="keywordtype">int</span> sustainVolume = psd.sustain * psd.volume / 127;</div><div class="line"></div><div class="line">  soundGenerator.attach( pwave);</div><div class="line">  pwave-&gt;setVolume( ((psd.attack == 0) ? ( (psd.decay != 0) ? psd.volume : sustainVolume) : 0) );</div><div class="line">  pwave-&gt;setFrequency( psd.freq_start );</div><div class="line">  pwave-&gt;enable(<span class="keyword">true</span> );</div><div class="line"></div><div class="line">  <span class="keywordtype">long</span> startTime = millis();</div><div class="line"></div><div class="line">  <span class="keywordflow">while</span> ( millis() - startTime &lt; psd.durationms)</div><div class="line">  {</div><div class="line">    <span class="keywordtype">long</span> current = millis() - startTime;</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> ( current &lt; psd.attack ) <span class="comment">// ATTACK VOLUME</span></div><div class="line">      pwave-&gt;setVolume( (psd.volume * current) / psd.attack );</div><div class="line">    <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( current &gt; psd.attack &amp;&amp; current &lt; (psd.attack + psd.decay)) <span class="comment">// DECAY VOLUME</span></div><div class="line">      pwave-&gt;setVolume( map( current - psd.attack,  0, psd.decay,  psd.volume, sustainVolume ) );</div><div class="line">    <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( current &gt; psd.durationms - psd.release) <span class="comment">// RELEASE VOLUME</span></div><div class="line">      pwave-&gt;setVolume( map( current - (psd.durationms - psd.release),  0, psd.release,  sustainVolume, 0 ) );</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">      pwave-&gt;setVolume( sustainVolume );</div><div class="line"></div><div class="line"></div><div class="line">    <span class="keywordflow">if</span> ( psd.modfreq != MODFREQ_NONE)</div><div class="line">    {</div><div class="line">      <span class="keywordtype">int</span> maxtime = psd.durationms;</div><div class="line">      <span class="keywordflow">if</span>      (psd.modfreq == MODFREQ_TO_RELEASE)</div><div class="line">        maxtime = (psd.durationms - psd.release); <span class="comment">// until release</span></div><div class="line">      <span class="keywordflow">else</span> <span class="keywordflow">if</span> (psd.modfreq == MODFREQ_TO_SUSTAIN)</div><div class="line">        maxtime = (psd.attack + psd.decay); <span class="comment">// until sustain</span></div><div class="line"></div><div class="line">      <span class="keywordtype">int</span> f = ((current &gt; maxtime) ? psd.freq_end : (map(current, 0, maxtime, psd.freq_start, psd.freq_end)));</div><div class="line">      pwave-&gt;setFrequency ( f ) ;</div><div class="line">    }</div><div class="line">    vTaskDelay(5);</div><div class="line">  }</div><div class="line"></div><div class="line">  soundGenerator.detach( pwave);</div><div class="line">  pwave-&gt;enable( <span class="keyword">false</span> );</div><div class="line">  <span class="keyword">delete</span> pwave;</div><div class="line"></div><div class="line">  vTaskDelete( NULL );</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">void</span> playSound( playsounddata ps )</div><div class="line">{</div><div class="line">  <span class="comment">// Now set up two tasks to run independently.</span></div><div class="line">  xTaskCreatePinnedToCore( iPlaySound,  <span class="stringliteral">&quot;iPlaySound&quot;</span>,</div><div class="line">                           4096,  <span class="comment">// This stack size can be checked &amp; adjusted by reading the Stack Highwater</span></div><div class="line">                           &amp;ps, <span class="comment">// sound as parameters</span></div><div class="line">                           3,  <span class="comment">// Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.</span></div><div class="line">                           NULL,</div><div class="line">                           1);</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">void</span>  syncPlaySound( playsounddata psd)</div><div class="line">{</div><div class="line">  playSound( psd);</div><div class="line">  delay(psd.durationms);</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment">// note (C,D,E,F,G,A,B) + [#,b] + octave (2..7) + space + tempo (99..1)</span></div><div class="line"><span class="comment">// pause (P) + space + tempo (99.1)</span></div><div class="line"><span class="keywordtype">char</span> <span class="keyword">const</span> * noteToFreq(<span class="keywordtype">char</span> <span class="keyword">const</span> * note, <span class="keywordtype">int</span> * freq)</div><div class="line">{</div><div class="line">  uint16_t NIDX2FREQ[][12] = { {   66,   70,   74,   78,   83,   88,   93,   98,  104,  110,  117,  124 }, <span class="comment">// 2</span></div><div class="line">                               {  131,  139,  147,  156,  165,  175,  185,  196,  208,  220,  233,  247 }, <span class="comment">// 3</span></div><div class="line">                               {  262,  277,  294,  311,  330,  349,  370,  392,  415,  440,  466,  494 }, <span class="comment">// 4</span></div><div class="line">                               {  523,  554,  587,  622,  659,  698,  740,  784,  831,  880,  932,  988 }, <span class="comment">// 5</span></div><div class="line">                               { 1046, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976 }, <span class="comment">// 6</span></div><div class="line">                               { 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951 }, <span class="comment">// 7</span></div><div class="line">                             };</div><div class="line">  uint8_t NNAME2NIDX[] = {9, 11, 0, 2, 4, 5, 7};  <span class="comment">// A, B, C, D, E, F, G</span></div><div class="line">  *freq = 0;</div><div class="line">  <span class="keywordflow">while</span> (*note &amp;&amp; *note == <span class="charliteral">&#39; &#39;</span>)</div><div class="line">    ++note;</div><div class="line">  <span class="keywordflow">if</span> (*note == 0)</div><div class="line">    <span class="keywordflow">return</span> note;</div><div class="line">  <span class="keywordtype">int</span> noteIndex = (*note &gt;= <span class="charliteral">&#39;A&#39;</span> &amp;&amp; *note &lt;= <span class="charliteral">&#39;G&#39;</span> ? NNAME2NIDX[*note - <span class="charliteral">&#39;A&#39;</span>] : -2); <span class="comment">// -2 = pause</span></div><div class="line">  ++note;</div><div class="line">  <span class="keywordflow">if</span> (*note == <span class="charliteral">&#39;#&#39;</span>) {</div><div class="line">    ++noteIndex;</div><div class="line">    ++note;</div><div class="line">  } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (*note == <span class="charliteral">&#39;b&#39;</span>) {</div><div class="line">    --noteIndex;</div><div class="line">    ++note;</div><div class="line">  }</div><div class="line">  <span class="keywordtype">int</span> octave = *note - <span class="charliteral">&#39;0&#39;</span>;</div><div class="line">  ++note;</div><div class="line">  <span class="keywordflow">if</span> (noteIndex == -1) {</div><div class="line">    noteIndex = 11;</div><div class="line">    --octave;</div><div class="line">  } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (noteIndex == 12) {</div><div class="line">    noteIndex = 0;</div><div class="line">    ++octave;</div><div class="line">  }</div><div class="line">  <span class="keywordflow">if</span> (noteIndex &gt;= 0 &amp;&amp; noteIndex &lt;= 11 &amp;&amp; octave &gt;= 2 &amp;&amp; octave &lt;= 7)</div><div class="line">    *freq = NIDX2FREQ[octave - 2][noteIndex];</div><div class="line">  <span class="keywordflow">return</span> note;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">char</span> <span class="keyword">const</span> * noteToDelay(<span class="keywordtype">char</span> <span class="keyword">const</span> * note, <span class="keywordtype">int</span> * delayMS)</div><div class="line">{</div><div class="line">  *delayMS = 0;</div><div class="line">  <span class="keywordflow">while</span> (*note &amp;&amp; *note == <span class="charliteral">&#39; &#39;</span>)</div><div class="line">    ++note;</div><div class="line">  <span class="keywordflow">if</span> (*note == 0)</div><div class="line">    <span class="keywordflow">return</span> note;</div><div class="line">  <span class="keywordtype">int</span> val = atoi(note);</div><div class="line">  <span class="keywordflow">if</span> (val &gt; 0)</div><div class="line">    *delayMS = 1000 / val;</div><div class="line">  <span class="keywordflow">return</span> note + (val &gt; 9 ? 2 : 1);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">// 0,5 = cortxea, 1 = negra 2 = blanca...</span></div><div class="line"><span class="keywordtype">char</span> <span class="keyword">const</span> * noteToDelayEx(<span class="keywordtype">char</span> <span class="keyword">const</span> * note, <span class="keywordtype">int</span> * delayMS)</div><div class="line">{</div><div class="line">  *delayMS = 0;</div><div class="line">  <span class="keywordflow">while</span> (*note &amp;&amp; *note == <span class="charliteral">&#39; &#39;</span>)</div><div class="line">    ++note;</div><div class="line">  <span class="keywordflow">if</span> (*note == 0)</div><div class="line">    <span class="keywordflow">return</span> note;</div><div class="line">  <span class="keywordtype">double</span> val = atof(note);</div><div class="line">  <span class="keywordflow">if</span> (val &gt; 0)</div><div class="line">    *delayMS = 250 * val;</div><div class="line"></div><div class="line">  <span class="keywordflow">while</span> ((*note &amp;&amp; isdigit(*note)) || *note == <span class="charliteral">&#39;.&#39;</span>)</div><div class="line">    ++note;</div><div class="line">    </div><div class="line">  <span class="keywordflow">return</span> note;</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">void</span> play_song1(<span class="keywordtype">bool</span> overnote= <span class="keyword">false</span>)</div><div class="line">{</div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> * music = <span class="stringliteral">&quot;A4 4 A4 4 A#4 4 C5 4 C5 4 A#4 4 A4 4 G4 4 F4 4 F4 4 G4 4 A4 4 A4 2 G4 16 G4 2 P 8 &quot;</span></div><div class="line">                       <span class="stringliteral">&quot;A4 4 A4 4 A#4 4 C5 4 C5 4 A#4 4 A4 4 G4 4 F4 4 F4 4 G4 4 A4 4 G4 2 F4 16 F4 2 P 8&quot;</span>;</div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> * m = music;</div><div class="line"></div><div class="line">  <span class="keywordflow">while</span> (*m ) </div><div class="line">  {</div><div class="line">    <span class="keywordtype">int</span> freq, delms;</div><div class="line">    m = noteToFreq(m, &amp;freq);</div><div class="line">    m = noteToDelay(m, &amp;delms);</div><div class="line">    playSound (  {250, 189, 120, 256, WAVE_TRIANGLE, 127, delms, freq, 0, MODFREQ_NONE} );     </div><div class="line">    <span class="keywordflow">if</span> (overnote)</div><div class="line">      playSound (  {500, 189, 120, 256, WAVE_SINE, 127, (delms*3)/2, freq/2, 0, MODFREQ_NONE} );     </div><div class="line">    delay(delms); </div><div class="line">  }</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keywordtype">void</span> play_song2()</div><div class="line">{</div><div class="line">   <span class="keyword">const</span> <span class="keywordtype">char</span> * track1 =  <span class="stringliteral">&quot;D5 1 D5 1 B4 1 D5 1 E5 1 D5 1 B4 2 B4 1 A4 3 B4 1 A4 3 D5 1 D5 1 B4 1 D5 1 E5 1 D5 1 B4 2 A4 2 B4 1 A4 1 G4 4&quot;</span></div><div class="line">                        <span class="stringliteral">&quot;D5 1 D5 1 B4 1 D5 1 E5 1 D5 1 B4 2 B4 1 A4 3 B4 1 A4 3 D5 1 D5 1 B4 1 D5 1 E5 1 D5 1 B4 2 A4 2 B4 1 A4 1 G4 4 &quot;</span></div><div class="line">                        <span class="stringliteral">&quot;G4 1.5 G4 0.5 B4 1 D5 1 G5 4 E5 1.5 E5 0.5 G5 1 E5 1 D5 4 D5 1 D5 1 B4 1 D5 1 E5 1 D5 1 B4 2 A4 1 C5 1 B4 1 A4 1 G4 4&quot;</span>;</div><div class="line"></div><div class="line">   <span class="keyword">const</span> <span class="keywordtype">char</span> * track2 =  <span class="stringliteral">&quot;B4 1 B4 1 G4 1 B4 1 C5 1 B4 1 G4 2 D4 1 D4 3 D4 1 D4 3 B4 1 B4 1 G4 1 B4 1 C5 1 B4 1 G4 2 D4 2 D4 1 D4 1 G4 4 &quot;</span></div><div class="line">                          <span class="stringliteral">&quot;B4 1 B5 1 G4 1 B5 1 C5 1 B5 1 G4 2 D4 1 D4 3 D4 1 D4 3 B4 1 B5 1 G4 1 B5 1 C5 1 B5 1 G4 2 D4 2 D4 1 D4 1 G4 4 &quot;</span></div><div class="line">                          <span class="stringliteral">&quot;G3 2 G4 2 G3 2 G4 2 E4 2 E5 2 D3 2 D4 2 D4 2 D5 2 C5 1 B4 1 G4 2 D4 2 D4 1 D4 1 G4 4 &quot;</span></div><div class="line">                          ;</div><div class="line"></div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> * track3 =  </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 4 &quot;</span></div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 0.5 A4 0.5 A4 0.5 A4 0.5 A4 1 A4 1 A4 4 &quot;</span></div><div class="line">  <span class="stringliteral">&quot;A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 &quot;</span>                     </div><div class="line">  <span class="stringliteral">&quot;A4 1 A4 0.5 A4 0.5 A4 1 A4 0.5 A4 0.5 A4 4&quot;</span>;</div><div class="line">   </div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> * m1 = track1;  </div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> * m2 = track2;</div><div class="line">  <span class="keyword">const</span> <span class="keywordtype">char</span> * m3 = track3;</div><div class="line">  <span class="keywordtype">long</span> track1_untilms = millis();  </div><div class="line">  <span class="keywordtype">long</span> track2_untilms = track1_untilms;  </div><div class="line">  <span class="keywordtype">long</span> track3_untilms = track1_untilms;  </div><div class="line"></div><div class="line">  <span class="keywordtype">int</span> previousfreq = -1;</div><div class="line">  <span class="keywordtype">int</span> previousfreq2 = -1;</div><div class="line">  </div><div class="line">  <span class="keywordflow">while</span> (*m1) </div><div class="line">  {</div><div class="line">    <span class="keywordtype">long</span> now = millis();</div><div class="line">    </div><div class="line">    <span class="keywordflow">if</span>(now &gt;= track1_untilms)    </div><div class="line">    {</div><div class="line">      <span class="keywordtype">int</span> freq, delms;</div><div class="line">      m1 = noteToFreq(m1, &amp;freq);</div><div class="line">      m1 = noteToDelayEx(m1, &amp;delms);</div><div class="line">      track1_untilms += delms;      </div><div class="line">      <span class="keywordflow">if</span> ( freq != 0)</div><div class="line">        playSound (  {75, 0, 127, 256, WAVE_SINE, 127, delms, previousfreq==-1?freq:previousfreq, freq, MODFREQ_TO_SUSTAIN} );      </div><div class="line">      previousfreq = freq;   </div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span>(now &gt;= track2_untilms &amp;&amp; *m2)    </div><div class="line">    {</div><div class="line">      <span class="keywordtype">int</span> freq, delms;</div><div class="line">      m2 = noteToFreq(m2, &amp;freq);</div><div class="line">      m2 = noteToDelayEx(m2, &amp;delms);</div><div class="line">      track2_untilms += delms;      </div><div class="line">      <span class="keywordflow">if</span>( freq != 0)        </div><div class="line">        playSound (  {10, 10, 100, 512, WAVE_SQUARE, 60, delms, previousfreq2==-1?freq:previousfreq2, freq, MODFREQ_TO_SUSTAIN} );   </div><div class="line">        previousfreq2 = freq;           </div><div class="line">    }</div><div class="line"></div><div class="line">    <span class="keywordflow">if</span>(now &gt;= track3_untilms &amp;&amp; *m3)    </div><div class="line">    {</div><div class="line">      <span class="keywordtype">int</span> freq, delms;</div><div class="line">      m3 = noteToFreq(m3, &amp;freq);</div><div class="line">      m3 = noteToDelayEx(m3, &amp;delms);      </div><div class="line">      track3_untilms += delms;      </div><div class="line">      <span class="keywordflow">if</span>( freq != 0)</div><div class="line">        playSound (  {0, 25, 120, 512, WAVE_NOISE, 127, delms/12, freq, 0, MODFREQ_NONE} );      </div><div class="line">    }    </div><div class="line">     delay(2);</div><div class="line">  }</div><div class="line">  <span class="keywordflow">while</span>(millis() &gt;= track1_untilms)  vTaskDelay(1);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">void</span> loop() {</div><div class="line">  play_song1(); </div><div class="line">  delay(2000); </div><div class="line">  play_song1(<span class="keyword">true</span> ); </div><div class="line">  delay(2000); </div><div class="line">  play_song2();  </div><div class="line">  delay(2000);    </div><div class="line">  Terminal.println( <span class="stringliteral">&quot;That&#39;s all folks...&quot;</span> );</div><div class="line">}</div></div><!-- fragment --> </div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Mon Aug 2 2021 07:08:02 for FabGL by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.8.14 </li>
  </ul>
</div>
</body>
</html>
